package com.threeti.mecool.core.domain.model.plan;

import com.threeti.mecool.core.domain.model.plan.pojo.Step;
import com.threeti.mecool.core.domain.model.plan.pojo.TaskActionDataType;
import com.threeti.mecool.core.infrastructure.persistence.plan.TaskActionDataTypeRepository;
import com.threeti.mecool.core.infrastructure.persistence.plan.UserStepResultRepository;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import javax.annotation.Resource;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;

@Configurable
@Entity
@Table(name = "DM_WF_USER_STEP_RESULT")
public class UserStepResult {
    public static final String STORE_SYNC_DONE = "sync_done";
    public static final String STORE_SYNC_OBSOLETE = "sync_obsolete";

    private Long id;
    private Integer version;
    private String userLoginName;
    private PlanJobResult planJobResult;
    private Step step;
    private int actionId;
    private long dataTypeId;
    private String data;
    private String dataExtra;
    private Date finishedAt;
    private Double latitude;
    private Double longitude;
    private UserStepResultRepository repository;
    private TaskActionDataTypeRepository taskActionDataTypeRepo;

    //jay:redundant gift for reporting&searching ->
    private String storeCode;
    //private String storeChannelName;
    private String empName;
    private String projectCode;
    private String projectName;
    //<-
    private String dataTypeCode;
    private String storeSyncStatus;
    private String gpsSyncStatus;

    public static UserStepResult findByIdWithDataTypeCode(Long id) {
        UserStepResult usr = repository().findOne(id);
        TaskActionDataType tadt = tadtRepo().findOne(usr.getDataTypeId());
        if (tadt != null) usr.setDataTypeCode(tadt.getCode());
        return usr;
    }

    public static UserStepResult findByStepAndPlanJob(String userLoginName, Long stepId, Long planJobId) {
        return repository().findByUserLoginNameAndStep_IdAndPlanJobResult_PlanJob_Id(userLoginName, stepId, planJobId);
    }

    public static Page<UserStepResult> findByProjectCategoryId(Long projectCategoryId, Pageable pageable) {
        return repository().findByProjectCategoryId(projectCategoryId, pageable);
    }

    public static Page<UserStepResult> findBySpec(Specification<UserStepResult> spec, Pageable pageable) {
        Page<UserStepResult> usrs = repository().findAll(spec, pageable);

        TaskActionDataTypeRepository tadtRepo = tadtRepo();
        for (UserStepResult usr : usrs) {
            TaskActionDataType tadt;
            if ((tadt = tadtRepo.findOne(usr.getDataTypeId())) != null) usr.setDataTypeCode(tadt.getCode());
        }
        return usrs;
    }

    public static UserStepResult findOne(Long id) {
        return repository().findOne(id);
    }

    //<editor-fold desc="get/set">
    private static UserStepResultRepository repository() {
        return new UserStepResult().repository;
    }

    private static TaskActionDataTypeRepository tadtRepo() {
        return new UserStepResult().taskActionDataTypeRepo;
    }

    public void save() {
        repository.save(this);
    }

    @Resource
    public void setRepository(UserStepResultRepository repository) {
        this.repository = repository;
    }

    @Resource
    public void setTaskActionDataTypeRepo(TaskActionDataTypeRepository taskActionDataTypeRepo) {
        this.taskActionDataTypeRepo = taskActionDataTypeRepo;
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    @Version
    public Integer getVersion() {
        return version;
    }

    @NotNull
    public String getUserLoginName() {
        return userLoginName;
    }

    @ManyToOne
    public PlanJobResult getPlanJobResult() {
        return planJobResult;
    }

    @ManyToOne
    public Step getStep() {
        return step;
    }

    public int getActionId() {
        return actionId;
    }

    public long getDataTypeId() {
        return dataTypeId;
    }

    @Size(max = 200)
    public String getData() {
        return data;
    }

    public String getDataExtra() {
        return dataExtra;
    }

    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    public Date getFinishedAt() {
        return finishedAt;
    }

    public Double getLongitude() {
        return longitude;
    }

    public Double getLatitude() {
        return latitude;
    }

    public String getStoreSyncStatus() {
        return storeSyncStatus == null ? "" : storeSyncStatus;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public void setUserLoginName(String userLoginName) {
        this.userLoginName = userLoginName;
    }

    public void setPlanJobResult(PlanJobResult planJobResult) {
        this.planJobResult = planJobResult;
    }

    public void setStep(Step step) {
        this.step = step;
    }

    public void setActionId(int actionId) {
        this.actionId = actionId;
    }

    public void setDataTypeId(long dataTypeId) {
        this.dataTypeId = dataTypeId;
    }

    public void setData(String data) {
        this.data = data;
    }

    public void setDataExtra(String dataExtra) {
        this.dataExtra = dataExtra;
    }

    public void setFinishedAt(Date finishedAt) {
        this.finishedAt = finishedAt;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }

    public String getStoreCode() {
        return storeCode;
    }

    public void setStoreCode(String storeCode) {
        this.storeCode = storeCode;
    }

    @Transient
    public String getStoreChannelName() {
        if (this.getPlanJobResult() == null) return "";
        if (this.getPlanJobResult().getChannel() == null) return "";
        if (this.getPlanJobResult().getChannel().getChannel() == null) return "";
        return this.getPlanJobResult().getChannel().getChannel().getName();
    }
//
//    public void setStoreChannelName(String storeChannelName) {
//      this.storeChannelName = storeChannelName;
//    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public String getProjectCode() {
        return projectCode;
    }

    public void setProjectCode(String projectCode) {
        this.projectCode = projectCode;
    }

    public String getProjectName() {
        return projectName;
    }

    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }

    public void setStoreSyncStatus(String storeSyncStatus) {
        this.storeSyncStatus = storeSyncStatus;
    }

    public String getGpsSyncStatus() {
        return gpsSyncStatus;
    }

    public void setGpsSyncStatus(String gpsSyncStatus) {
        this.gpsSyncStatus = gpsSyncStatus;
    }
    //</editor-fold>

    @Transient
    public String getDataTypeCode() {
        return dataTypeCode;
    }

    public void setDataTypeCode(String dataTypeCode) {
        this.dataTypeCode = dataTypeCode;
    }

    @Transient
    public UserStepResultRepository getRepository() {
        return repository;
    }

    @Transient
    public TaskActionDataTypeRepository getTaskActionDataTypeRepo() {
        return taskActionDataTypeRepo;
    }

    public UserStepResult() {
    }

    /**
     * 冗余持久相关属性
     */
    void saveRedundantProperties() {
        PlanJobResult jobResult;
        if ((jobResult = this.getPlanJobResult()) != null) {
            this.storeCode = jobResult.getStoreCode();
            //this.storeChannelName = jobResult.getStoreChannelName();
            this.empName = jobResult.getEmpName();
            this.projectCode = jobResult.getProjectCode();
            this.projectName = jobResult.getProjectName();
        }
    }
}
